#pragma once
#include "util.hpp"
#include "qbe/src/utils/utils.hpp"
namespace qbe::editing::BooleanOperation {

std::string getOperationObjectInfo(QString text, BooleanOperationModel& model) {
  // 区分对象是否用图层描述(即对象是否大于2)
  if (model.m_operate_select_arr.size() == 2) {
    // 区分运算方式(是否显示位置关系)
    if (text == "AND" || text == "XOR") {
      return makeInfoByShape(false,model);
    }

    if (text == "A-B" || text == "B-A") {
      return makeInfoByShape(true,model);
    }
  }

  if (model.m_operate_select_arr.size() >= 2) {   //对象数量大于2
    if (model.m_select_layer_set.size() != 2) {  //图层数量不为2
      model.m_ok_enable = false;
      return QObject::tr("Cannot operate, please select two objects or any object with only two layers").toStdString();
    } else {
      return makeInfoByLayer(model);
    }
  }

  return std::string();
}



std::string makeInfoByShape(bool show_position,BooleanOperationModel& model) {
  model.m_element_a = model.m_operate_select_arr[0];
  model.m_element_b = model.m_operate_select_arr[1];
  bool is_up_down_relation = true;  // 是否上下关系

  // 计算位置关系
  qlib::Vec2dArray obb_first =  qbe::utils::getBox(model.cell->reg,  model.m_operate_select_arr[0].first);    
  qlib::Vec2dArray obb_second = qbe::utils::getBox(model.cell->reg,  model.m_operate_select_arr[1].first);   

  if (obb_first[1].y == obb_second[1].y) {
    //两个对象上边缘重合，计算左右关系
    if (obb_first[0].x == obb_second[0].x) {
      //左右上下均重合 默认上下关系
    } else if (obb_first[0].x < obb_second[0].x) {
      is_up_down_relation = false;
    } else if (obb_first[0].x > obb_second[0].x) {
      is_up_down_relation = false;
      model.m_element_a = model.m_operate_select_arr[1];
      model.m_element_b = model.m_operate_select_arr[0];
    }
  } else if (obb_first[1].y < obb_second[1].y) {
    model.m_element_a = model.m_operate_select_arr[1];
    model.m_element_b = model.m_operate_select_arr[0];
  }

  std::string shape_a = getEntityTypeToString(model.m_element_a.first,model);
  std::string layer_name_a;
  long long layer_a = model.m_element_a.second[0]->layer;

  std::vector<std::string> layer_style_a = model.layer_interface.getLayerStyleInfoOnNumFunc(layer_a);
  if (layer_style_a.size() == 7) {
    layer_name_a = layer_style_a[4];
  }

  std::string shape_b = getEntityTypeToString(model.m_element_b.first,model);
  std::string layer_name_b;
  long long layer_b = model.m_element_b.second[0]->layer;
  std::vector<std::string> layer_style_b = model.layer_interface.getLayerStyleInfoOnNumFunc(layer_b);
  if (layer_style_b.size() == 7) {
    layer_name_b = layer_style_b[4];
  }

  std::string position_a = "";
  std::string position_b = "";
  if (show_position == true) {
    if (is_up_down_relation == true) {
      position_a = QObject::tr("(up)").toStdString();
      position_b = QObject::tr("(down)").toStdString();
    } else {
      position_a = QObject::tr("(left)").toStdString();
      position_b = QObject::tr("(right)").toStdString();
    }
  }

  std::string object_info_A = "A: " + position_a + shape_a + " ---- " + layer_name_a + "/" + std::to_string(layer_a);
  std::string object_info_B = "B: " + position_b + shape_b + " ---- " + layer_name_b + "/" + std::to_string(layer_b);

  std::string info = object_info_A + "\n" + object_info_B;

  return info;
}

std::string makeInfoByLayer(BooleanOperationModel& model) {
  std::vector<uint32_t> layer_vec;
  for (auto& it : model.m_select_layer_set) {
    layer_vec.push_back(it);
  }
  uint32_t layer_a = layer_vec[0];
  uint32_t layer_b = layer_vec[1];

  if (layer_a > layer_b) {
    uint32_t temp_layer = layer_a;
    layer_a = layer_b;
    layer_b = temp_layer;
  }

  std::string layer_name_a;
  std::string layer_name_b;

  std::vector<std::string> layer_style_a = model.layer_interface.getLayerStyleInfoOnNumFunc(layer_a);
  if (layer_style_a.size() == 7) {
    layer_name_a = layer_style_a[4];
  }

  std::vector<std::string> layer_style_b = model.layer_interface.getLayerStyleInfoOnNumFunc(layer_b);
  if (layer_style_b.size() == 7) {
    layer_name_b = layer_style_b[4];
  }

  QString object_info_A =
      QObject::tr("A: use ") + QString::fromStdString(layer_name_a) + "/" + QString::number(layer_a) + QObject::tr(" all objects");
  QString object_info_B =
      QObject::tr("B: use ") + QString::fromStdString(layer_name_b) + "/" + QString::number(layer_b) + QObject::tr(" all objects");

  QString info = object_info_A + "\n" + object_info_B;

  return info.toStdString();
}


std::string getEntityTypeToString(entt::entity e,BooleanOperationModel& model) {
  auto& reg = model.cell->reg;
    auto ellipse_ptr = reg.try_get<qlib::Ellipse::s_ptr>(e);
    if (ellipse_ptr) {

      return QObject::tr("ellipse").toStdString();
    }

    auto rectangle_ptr = reg.try_get<qlib::Rectangle::s_ptr>(e);
    if (rectangle_ptr) {
      return QObject::tr("rectangle").toStdString();
    }

    auto polygon_ptr = reg.try_get<qlib::Polygon::s_ptr>(e);
    if (polygon_ptr) {

    }

    auto fan_ptr = reg.try_get<qlib::Fan::s_ptr>(e);
    if (fan_ptr) {
            qlib::Polygon::s_ptr pol = (*fan_ptr)->to_polygon();
      return QObject::tr("polygon").toStdString();
    }

    // auto path_ptr = reg.try_get<qlib::Path::s_ptr>(e);
    // if (path_ptr && (*path_ptr)->have_width == true) {
    //         qlib::Polygon::s_ptr pol = (*path_ptr)->to_polygon();
    //   operate_select_arr.push_back(std::make_pair(e,pol));
    //         select_layer_set.insert((*path_ptr)->layer);
       //   return tr("line").toStdString();
    // }
  return std::string();
}

}


